#include "TabelaHash.h"

/*
 * @resume: construtor da classe TabelaHash
 */
TabelaHash::TabelaHash() {

}

/*
 * @resume: destrutor da classe TabelaHash
 */
TabelaHash::~TabelaHash() {

}

/*
 * @resume: metodo utilizado para adicionar elementos na tabela hash
 * @param: IdentificadorGenerico *identificador
 */
void TabelaHash::addHash(IdentificadorGenerico *identificador) {
	this->hashTable.insert(pair<int, IdentificadorGenerico*> (funcaoHash(
			identificador->getIdentificador()), identificador));
}

/*
 * @resume: metodo utilizado para buscar algum noh da tabela hash
 * @return: IdentificadorGenerico *identificador
 */
IdentificadorGenerico *TabelaHash::buscarNoh(string identificador,
		string procedimento) {

	IdentificadorGenerico *idProcurado = NULL;
	for (this->it = this->hashTable.begin(); this->it != this->hashTable.end(); this->it++) {
		if ((*it).first == funcaoHash(identificador)) {
			idProcurado = (*it).second;
			if (idProcurado->getProcedimentoPaiIdentificador().compare(
					procedimento) == 0) {
				break;
			}
		}
	}
	return (idProcurado);
}

/*
 * @resume: metodo utilizado para verificar se existe algum noh da tabela hash
 * @return: true: se existe
 * 			false: se nao
 */
bool TabelaHash::existeNoh(string identificador, string procedimento) {
	for (this->it = this->hashTable.begin(); this->it != this->hashTable.end(); this->it++) {
		if (((*(this->it)).first == funcaoHash(identificador))
				&& ((*(this->it)).second->getProcedimentoPaiIdentificador()
						== procedimento)) {
			return (true);
		}
	}
	return (false);
}

/*
 * @resume: funcao hash para gerar o indice
 * @return: int gama % NUMERO_PRIMO
 */
int TabelaHash::funcaoHash(string identificador) {
	int alpha = 6;
	unsigned int gama = 0;
	for (unsigned i = 0; i < identificador.length(); i++) {
		gama = alpha * gama + (int) identificador[i];
	}
	return (gama % NUMERO_PRIMO);
}

/*
 * @resume: metodo utilizado para imprimir a tabela hash arquivo de saida (hashTable.txt)
 * @param: char* endFileOut
 */
void TabelaHash::showHashTable(char* endFileOut) {
	int numeroIdentificador = 0;
	string numero = "";
	this->fileOut.setEnd(endFileOut);
	this->fileOut.abrir(fstream::out);
	this->fileOut.write(
			"  ********************************************************************************** \n");
	this->fileOut.write(
			"  *Alunos:     Pedro Sanches Junior                                                * \n");
	this->fileOut.write(
			"  *            Thiago Augusto Lopes Genez                                          * \n");
	this->fileOut.write(
			"  *                                                                                * \n");
	this->fileOut.write(
			"  *Professora: Cintyan                                                             * \n");
	this->fileOut.write(
			"  *                                                                                * \n");
	this->fileOut.write(
			"  *Disciplina: Compiladores                                                        * \n");
	this->fileOut.write(
			"  ********************************************************************************** \n\n");
	this->fileOut.write(
			"  ---------------------------------------------------------------------------------- \n");
	this->fileOut.write(
			" |     T A B E L A    D E    S I M B O L O S    -    H A S H    T A B L E           |\n");
	this->fileOut.write(
			" |__________________________________________________________________________________|\n");

	if (!this->hashTable.empty()) {
		for (this->it = this->hashTable.begin(); this->it
				!= this->hashTable.end(); this->it++) {
			IdentificadorGenerico *id = (*(this->it)).second;
			this->fileOut.write(" | Identificador Indice: " + id->IntToString(
					(*(this->it)).first) + "\n");
			id->show(this->fileOut);
			numeroIdentificador++;
			this->fileOut.write(" |\n");
			this->fileOut.write(
					" |--------------------------------------------------------------------------------- \n");
			this->fileOut.write(" |\n");
		}
		this->fileOut.write(" | Total de Identificadores: "
				+ this->IntToString(numeroIdentificador) + "\n");
		this->fileOut.write(
				"  ---------------------------------------------------------------------------------- \n");
	} else {

		this->fileOut.write(
				"  *Tabela Hash Vazia!!!                                                            * \n");
		this->fileOut.write(
				"  ---------------------------------------------------------------------------------- \n");
	}

	this->fileOut.fechar();
}

/*
 * @resume: metodo utilizado para transformar um int em string
 * @return: string num
 */
string TabelaHash::IntToString(int num) {
	stringstream out;
	out << num;
	return (out.str());
}
